<template>
  <div class="panel-tab__content">
    <el-form label-width="70px" @submit.prevent size="small">
      <el-form-item label="参数说明">
        <el-button size="small" type="primary" @click="dialogVisible = true"
          >查看</el-button
        >
      </el-form-item>
      <el-form-item label="回路特性">
        <el-select
          v-model="loopCharacteristics"
          @change="changeLoopCharacteristicsType"
        >
          <el-option label="并行多重事件" value="ParallelMultiInstance" />
          <el-option label="时序多重事件" value="SequentialMultiInstance" />
          <el-option label="循环事件" value="StandardLoop" />
          <el-option label="无" value="Null" />
        </el-select>
      </el-form-item>
      <template
        v-if="
          loopCharacteristics === 'ParallelMultiInstance' ||
          loopCharacteristics === 'SequentialMultiInstance'
        "
      >
        <el-form-item label="循环基数" key="loopCardinality">
          <el-input
            v-model="loopInstanceForm.loopCardinality"
            clearable
            @change="updateLoopCardinality"
          />
        </el-form-item>
        <el-form-item label="集合" key="collection">
          <el-input
            v-model="loopInstanceForm.collection"
            clearable
            @change="updateLoopBase"
          />
        </el-form-item>
        <el-form-item label="元素变量" key="elementVariable">
          <el-input
            v-model="loopInstanceForm.elementVariable"
            clearable
            @change="updateLoopBase"
          />
        </el-form-item>
        <el-form-item label="完成条件" key="completionCondition">
          <el-input
            v-model="loopInstanceForm.completionCondition"
            clearable
            @change="updateLoopCondition"
          />
        </el-form-item>
        <el-form-item label="异步状态" key="async">
          <el-checkbox
            v-model="loopInstanceForm.asyncBefore"
            label="异步前"
            @change="() => updateLoopAsync('asyncBefore')"
          />
          <el-checkbox
            v-model="loopInstanceForm.asyncAfter"
            label="异步后"
            @change="() => updateLoopAsync('asyncAfter')"
          />
          <el-checkbox
            v-model="loopInstanceForm.exclusive"
            v-if="loopInstanceForm.asyncAfter || loopInstanceForm.asyncBefore"
            label="排除"
            @change="() => updateLoopAsync('exclusive')"
          />
        </el-form-item>
        <el-form-item
          label="重试周期"
          prop="timeCycle"
          v-if="loopInstanceForm.asyncAfter || loopInstanceForm.asyncBefore"
          key="timeCycle"
        >
          <el-input
            v-model="loopInstanceForm.timeCycle"
            clearable
            @change="updateLoopTimeCycle"
          />
        </el-form-item>
      </template>
    </el-form>

    <!-- 参数说明 -->
    <el-dialog
      title="多实例参数"
      v-model="dialogVisible"
      width="680px"
      @closed="$emit('close')"
    >
      <el-descriptions :column="1" border>
        <el-descriptions-item label="使用说明"
          >按照BPMN2.0规范的要求，用于为每个实例创建执行的父执行，会提供下列变量:</el-descriptions-item
        >
        <el-descriptions-item label="collection(集合变量)"
          >传入List参数, 一般为用户ID集合</el-descriptions-item
        >
        <el-descriptions-item label="elementVariable(元素变量)"
          >List中单个参数的名称</el-descriptions-item
        >
        <el-descriptions-item label="loopCardinality(基数)"
          >List循环次数</el-descriptions-item
        >
        <el-descriptions-item label="isSequential(串并行)"
          >Parallel: 并行多实例，Sequential: 串行多实例</el-descriptions-item
        >
        <el-descriptions-item label="completionCondition(完成条件)"
          >任务出口条件</el-descriptions-item
        >
        <el-descriptions-item label="nrOfInstances(实例总数)"
          >实例总数</el-descriptions-item
        >
        <el-descriptions-item label="nrOfActiveInstances(未完成数)"
          >当前活动的（即未完成的），实例数量。对于顺序多实例，这个值总为1</el-descriptions-item
        >
        <el-descriptions-item label="nrOfCompletedInstances(已完成数)"
          >已完成的实例数量</el-descriptions-item
        >
        <el-descriptions-item label="loopCounter"
          >给定实例在for-each循环中的index</el-descriptions-item
        >
      </el-descriptions>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, watch, onMounted } from "vue";
import { StrUtil } from "@/utils/StrUtil";

import modelerStore from "@/components/Process/common/global";
const props = defineProps({
  id: {
    type: String,
    required: true,
  },
});

const dialogVisible = ref(false);
const loopCharacteristics = ref("");
const loopInstanceForm = ref({});
const multiLoopInstance = ref({});
const defaultLoopInstanceForm = ref({
  completionCondition: "",
  loopCardinality: "",
  extensionElements: [],
  asyncAfter: false,
  asyncBefore: false,
  exclusive: false,
});

watch(
  () => props.id,
  (newVal) => {
    if (StrUtil.isNotBlank(newVal)) {
      getElementLoop(modelerStore.element.businessObject);
    }
  },
  { immediate: true }
);

function getElementLoop(businessObject) {
  if (!businessObject.loopCharacteristics) {
    loopCharacteristics.value = "Null";
    loopInstanceForm.value = {};
    return;
  }
  if (
    businessObject.loopCharacteristics.$type ===
    "bpmn:StandardLoopCharacteristics"
  ) {
    loopCharacteristics.value = "StandardLoop";
    loopInstanceForm.value = {};
    return;
  }
  if (businessObject.loopCharacteristics.isSequential) {
    loopCharacteristics.value = "SequentialMultiInstance";
  } else {
    loopCharacteristics.value = "ParallelMultiInstance";
  }
  loopInstanceForm.value = {
    ...defaultLoopInstanceForm.value,
    ...businessObject.loopCharacteristics,
    completionCondition:
      businessObject.loopCharacteristics?.completionCondition?.body ?? "",
    loopCardinality:
      businessObject.loopCharacteristics?.loopCardinality?.body ?? "",
  };
  multiLoopInstance.value =
    modelerStore.element.businessObject.loopCharacteristics;
  if (
    businessObject.loopCharacteristics.extensionElements &&
    businessObject.loopCharacteristics.extensionElements.values &&
    businessObject.loopCharacteristics.extensionElements.values.length
  ) {
    loopInstanceForm.value.timeCycle =
      businessObject.loopCharacteristics.extensionElements.values[0].body;
  }
}

const changeLoopCharacteristicsType = (type) => {
  loopInstanceForm.value = { ...defaultLoopInstanceForm.value };
  if (type === "Null") {
    modelerStore.modeling.updateProperties(modelerStore.element, {
      loopCharacteristics: null,
    });
    return;
  }
  if (type === "StandardLoop") {
    const loopCharacteristicsObject = modelerStore.moddle.create(
      "bpmn:StandardLoopCharacteristics"
    );
    modelerStore.modeling.updateProperties(modelerStore.element, {
      loopCharacteristics: loopCharacteristicsObject,
    });
    multiLoopInstance.value = null;
    return;
  }
  if (type === "SequentialMultiInstance") {
    multiLoopInstance.value = modelerStore.moddle.create(
      "bpmn:MultiInstanceLoopCharacteristics",
      {
        isSequential: true,
      }
    );
  } else {
    multiLoopInstance.value = modelerStore.moddle.create(
      "bpmn:MultiInstanceLoopCharacteristics"
    );
  }
  modelerStore.modeling.updateProperties(modelerStore.element, {
    loopCharacteristics: multiLoopInstance.value,
  });
};

const updateLoopCardinality = (cardinality) => {
  let loopCardinality = null;
  if (cardinality && cardinality.length) {
    loopCardinality = modelerStore.moddle.create(
      "bpmn:FormalExpression",
      { body: cardinality }
    );
  }
  modelerStore.modeling.updateModdleProperties(
    modelerStore.element,
    multiLoopInstance.value,
    {
      loopCardinality,
    }
  );
};

const updateLoopCondition = (condition) => {
  let completionCondition = null;
  if (condition && condition.length) {
    completionCondition = modelerStore.moddle.create(
      "bpmn:FormalExpression",
      { body: condition }
    );
  }
  modelerStore.modeling.updateModdleProperties(
    modelerStore.element,
    multiLoopInstance.value,
    {
      completionCondition,
    }
  );
};

const updateLoopTimeCycle = (timeCycle) => {
  const extensionElements = modelerStore.moddle.create(
    "bpmn:ExtensionElements",
    {
      values: [
        modelerStore.moddle.create(`flowable:FailedJobRetryTimeCycle`, {
          body: timeCycle,
        }),
      ],
    }
  );
  modelerStore.modeling.updateModdleProperties(
    modelerStore.element,
    multiLoopInstance.value,
    {
      extensionElements,
    }
  );
};
// 直接更新的基础信息
const updateLoopBase = () => {
  modelerStore.modeling.updateModdleProperties(
    modelerStore.element,
    multiLoopInstance.value,
    {
      collection: loopInstanceForm.value.collection || null,
      elementVariable: loopInstanceForm.value.elementVariable || null,
    }
  );
};

// 各异步状态
const updateLoopAsync = (key) => {
  const { asyncBefore, asyncAfter } = loopInstanceForm.value;
  let asyncAttr = {};

  if (!asyncBefore && !asyncAfter) {
    loopInstanceForm.value.exclusive = false;
    asyncAttr = {
      asyncBefore: false,
      asyncAfter: false,
      exclusive: false,
      extensionElements: null,
    };
  } else {
    asyncAttr[key] = loopInstanceForm.value[key];
  }

  modelerStore.modeling.updateModdleProperties(
    modelerStore.element,
    multiLoopInstance.value,
    asyncAttr
  );
};
</script>

<style lang="scss">
// @import '../style/process-panel';
.panel-tab__title {
  font-weight: 600;
  padding: 0 8px;
  font-size: 1.1em;
  line-height: 1.2em;
  i {
    margin-right: 8px;
    font-size: 1.2em;
  }
}
.panel-tab__content {
  width: 100%;
  box-sizing: border-box;
  //border-top: 1px solid #eeeeee;
  padding: 8px 16px;
  .panel-tab__content--title {
    display: flex;
    justify-content: space-between;
    padding-bottom: 8px;
    span {
      flex: 1;
      text-align: left;
    }
  }
}
.element-property {
  width: 100%;
  display: flex;
  align-items: flex-start;
  margin: 8px 0;
  .element-property__label {
    display: block;
    width: 90px;
    text-align: right;
    overflow: hidden;
    padding-right: 12px;
    line-height: 32px;
    font-size: 14px;
    box-sizing: border-box;
  }
  .element-property__value {
    flex: 1;
    line-height: 32px;
  }
  .el-form-item {
    width: 100%;
    margin-bottom: 0;
    padding-bottom: 18px;
  }
}
.list-property {
  flex-direction: column;
  .element-listener-item {
    width: 100%;
    display: inline-grid;
    grid-template-columns: 16px auto 32px 32px;
    grid-column-gap: 8px;
  }
  .element-listener-item + .element-listener-item {
    margin-top: 8px;
  }
}
.listener-filed__title {
  width: 100%;
  justify-content: space-between;
  align-items: center;
  margin-top: 0;
  span {
    font-size: 14px;
  }
  i {
    margin-right: 8px;
  }
}
.element-drawer__button {
  margin-top: 8px;
  display: inline-flex;
  justify-content: space-around;
}
.element-drawer__button > .el-button {
  width: 100%;
}

.element-drawer__button_save {
  margin-top: 8px;
  width: 100%;
  display: inline-flex;
  justify-content: space-around;
}
.element-drawer__button_save > .el-button {
  width: 100%;
}

.el-collapse-item__content {
  padding-bottom: 0;
}
.el-input.is-disabled .el-input__inner {
  color: #999999;
}
.el-form-item.el-form-item--mini {
  margin-bottom: 0;
  & + .el-form-item {
    margin-top: 16px;
  }
}
.el-drawer__header {
  margin-bottom: 0;
  border-bottom: 1px solid #e8e8e8;
  padding: 16px 16px 8px 16px;
  font-size: 18px;
  color: #303133;
}
.el-drawer__body {
  padding: 10px;
}
</style>
